/*
@Time : 2018/11/8 下午7:12 
@Author : baoye
@File : block
@Software: GoLand
@brief: 
*/

package main

import (
	"time"
	"bytes"
	"encoding/binary"
	"log"
	"encoding/gob"
	"fmt"
	"os"
	"crypto/sha256"
)

const genesisInfo  = "2009年1月3日，财政大臣正处于实施第二轮银行紧急援助的边缘"

type Block struct {
	Version uint64 // 版本号
	PrevBlockHash []byte // 前区块哈希值
	MerkelRoot []byte //这是一个哈希值，后面v5用到
	TimeStamp uint64 //时间戳，从1970.1.1到现在的秒数
	Difficulty uint64 //通过这个数字，算出一个哈希值：0x00010000000xxx
	Nonce uint64 // 这是我们要找的随机数，挖矿就找证书
	Hash []byte //当前区块哈希值, 正常的区块不存在，我们为了方便放进来
	//Data []byte //数据本身，区块体，先用字符串表示，v4版本的时候会引用真正的交易结构
	Transactions []*Transaction // 区块交易数据
}

func NewBlock(txs []*Transaction, prevHash []byte) *Block  {

	block := Block{
		Version:       00,
		PrevBlockHash: prevHash,
		TimeStamp:     uint64(time.Now().Unix()),
		Difficulty:    difficult,
		Transactions:  txs,
	}
	block.SetHash()
	block.MerkelRoot = HashTransactions(&block)
	return &block
}
func (block *Block)SetHash()  {

	pow := NewProofOfWork(*block)
	hash,nonce := pow.Run()

	block.Nonce = nonce
	block.Hash = hash[:]
}

func Uint2Byte(num uint64) []byte  {
	var buffer bytes.Buffer

	err := binary.Write(&buffer,binary.BigEndian,num)
	if err != nil {
		log.Panic(err)
	}

	return buffer.Bytes()
}
func (block *Block)Serialize()[]byte{
	var buffer bytes.Buffer
	encoder := gob.NewEncoder(&buffer)
	err := encoder.Encode(block)
	if err != nil {
		fmt.Println("encode failed!")
		os.Exit(1)
	}
	return buffer.Bytes()
}
func Deserialize(data []byte) Block{
	var buffer bytes.Buffer
	var block Block
	buffer.Write(data)
	decoder := gob.NewDecoder(&buffer)
	err := decoder.Decode(&block)
	if err != nil {
		fmt.Println("decode failed!")
		os.Exit(1)
	}

	return block
}
func HashTransactions(block *Block) []byte {

	var tmp [][]byte
	for _, tx := range block.Transactions{
		//交易的ID就是交易的哈希值，还记得吗？我们在Transaction里面提供了方法。
		tmp = append(tmp, tx.TXID)
	}

	data := bytes.Join(tmp, []byte{})
	hash := sha256.Sum256(data)

	return hash[:]
}